From e7fa0b981f193f6310119508edab1ab706187f52 Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Thu, 21 Dec 2023 13:57:44 +0100
Subject: [PATCH 1/5] feat: rename DEV domain to DEVNET domain
---
demos/taco-demo/src/config.ts | 2 +-
demos/taco-nft-demo/src/config.ts | 2 +-
packages/pre/test/acceptance/alice-grants.test.ts | 2 +-
packages/pre/test/acceptance/delay-enact.test.ts | 2 +-
packages/shared/src/porter.ts | 2 +-
packages/taco/test/taco.test.ts | 4 ++--
6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/demos/taco-demo/src/config.ts b/demos/taco-demo/src/config.ts
index 4f8cbe26e..3c07c378d 100644
--- a/demos/taco-demo/src/config.ts
+++ b/demos/taco-demo/src/config.ts
@@ -4,4 +4,4 @@ export const DEFAULT_RITUAL_ID =
(process.env.DEFAULT_RITUAL_ID && parseInt(process.env.DEFAULT_RITUAL_ID)) ||
24;
-export const DEFAULT_DOMAIN = process.env.DEFAULT_DOMAIN || domains.DEV;
+export const DEFAULT_DOMAIN = process.env.DEFAULT_DOMAIN || domains.DEVNET;
diff --git a/demos/taco-nft-demo/src/config.ts b/demos/taco-nft-demo/src/config.ts
index 4f8cbe26e..3c07c378d 100644
--- a/demos/taco-nft-demo/src/config.ts
+++ b/demos/taco-nft-demo/src/config.ts
@@ -4,4 +4,4 @@ export const DEFAULT_RITUAL_ID =
(process.env.DEFAULT_RITUAL_ID && parseInt(process.env.DEFAULT_RITUAL_ID)) ||
24;
-export const DEFAULT_DOMAIN = process.env.DEFAULT_DOMAIN || domains.DEV;
+export const DEFAULT_DOMAIN = process.env.DEFAULT_DOMAIN || domains.DEVNET;
diff --git a/packages/pre/test/acceptance/alice-grants.test.ts b/packages/pre/test/acceptance/alice-grants.test.ts
index d5f02c487..fdf88cbcd 100644
--- a/packages/pre/test/acceptance/alice-grants.test.ts
+++ b/packages/pre/test/acceptance/alice-grants.test.ts
@@ -73,7 +73,7 @@ describe('story: alice shares message with bob through policy', () => {
policy = await alice.grant(
fakeProvider(),
fakeSigner(),
- domains.DEV,
+ domains.DEVNET,
fakePorterUri,
policyParams,
);
diff --git a/packages/pre/test/acceptance/delay-enact.test.ts b/packages/pre/test/acceptance/delay-enact.test.ts
index efdb9f946..01cab8949 100644
--- a/packages/pre/test/acceptance/delay-enact.test.ts
+++ b/packages/pre/test/acceptance/delay-enact.test.ts
@@ -62,7 +62,7 @@ describe('story: alice creates a policy but someone else enacts it', () => {
const enacted = await preEnactedPolicy.enact(
provider,
fakeSigner(),
- domains.DEV,
+ domains.DEVNET,
);
expect(enacted.txHash).toBeDefined();
diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts
index d314a6870..7d78b5e65 100644
--- a/packages/shared/src/porter.ts
+++ b/packages/shared/src/porter.ts
@@ -22,7 +22,7 @@ const porterUri: Record = {
export type Domain = keyof typeof porterUri;
export const domains: Record = {
- DEV: 'lynx',
+ DEVNET: 'lynx',
TESTNET: 'tapir',
MAINNET: 'mainnet',
};
diff --git a/packages/taco/test/taco.test.ts b/packages/taco/test/taco.test.ts
index 398398c7a..e509b8f27 100644
--- a/packages/taco/test/taco.test.ts
+++ b/packages/taco/test/taco.test.ts
@@ -48,7 +48,7 @@ describe('taco', () => {
const messageKit = await taco.encrypt(
provider,
- domains.DEV,
+ domains.DEVNET,
message,
ownsNFT,
mockedDkg.ritualId,
@@ -81,7 +81,7 @@ describe('taco', () => {
const decryptedMessage = await taco.decrypt(
provider,
- domains.DEV,
+ domains.DEVNET,
messageKit,
fakePorterUri,
signer,
From 3bab0aed532dae174a8e74a0c2735958d99e4078 Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Thu, 21 Dec 2023 14:16:30 +0100
Subject: [PATCH 2/5] fix(ci): fix lynx job on ci
---
examples/taco/nodejs/src/index.ts | 4 ++--
packages/shared/package.json | 2 +-
pnpm-lock.yaml | 8 ++++----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/examples/taco/nodejs/src/index.ts b/examples/taco/nodejs/src/index.ts
index e9595823d..98f5960b7 100644
--- a/examples/taco/nodejs/src/index.ts
+++ b/examples/taco/nodejs/src/index.ts
@@ -32,8 +32,8 @@ if (!consumerPrivateKey) {
throw new Error('CONSUMER_PRIVATE_KEY is not set.');
}
-const domain = domains.TESTNET;
-const ritualId = 5; // Replace with your own ritual ID
+const domain = domains.DEVNET;
+const ritualId = 0; // Replace with your own ritual ID
const provider = new ethers.providers.JsonRpcProvider(rpcProviderUrl);
const encryptToBytes = async (messageString: string) => {
diff --git a/packages/shared/package.json b/packages/shared/package.json
index 533f75dcf..0a6d01497 100644
--- a/packages/shared/package.json
+++ b/packages/shared/package.json
@@ -42,7 +42,7 @@
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
- "@nucypher/nucypher-contracts": "^0.13.0",
+ "@nucypher/nucypher-contracts": "^0.15.0",
"@nucypher/nucypher-core": "*",
"axios": "^1.6.2",
"deep-equal": "^2.2.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d3edb9016..a27036326 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -486,8 +486,8 @@ importers:
specifier: ^5.7.2
version: 5.7.2
'@nucypher/nucypher-contracts':
- specifier: ^0.13.0
- version: 0.13.0
+ specifier: ^0.15.0
+ version: 0.15.0
'@nucypher/nucypher-core':
specifier: 0.13.0-alpha.1
version: 0.13.0-alpha.1
@@ -3593,8 +3593,8 @@ packages:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
- /@nucypher/nucypher-contracts@0.13.0:
- resolution: {integrity: sha512-QB9vCVq2mLR2SeA/gSX8Px2QW3wcc9keQuTwgtDOA5J7PLoxDHEAko4ow6ZlsfjsbK572Xz6YReH09MBr71ujA==}
+ /@nucypher/nucypher-contracts@0.15.0:
+ resolution: {integrity: sha512-AVAAJfCdymvaIPnT2fGCL096fNhw70a9OaHGgr6oTMqOeXmyl/ojHHW6FfFOcTToWVsnA5000dTbLe0lfFhrOg==}
dev: false
/@nucypher/nucypher-core@0.13.0-alpha.1:
From 87b945dc4a34d641dd14e85847c1ece820399f67 Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Thu, 21 Dec 2023 14:26:24 +0100
Subject: [PATCH 3/5] chore(examples): set domain and ritual id using env vars
---
examples/taco/nodejs/.env.example | 2 ++
examples/taco/nodejs/src/index.ts | 7 +++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/examples/taco/nodejs/.env.example b/examples/taco/nodejs/.env.example
index 97cc395f7..15e66f58c 100644
--- a/examples/taco/nodejs/.env.example
+++ b/examples/taco/nodejs/.env.example
@@ -5,3 +5,5 @@ RPC_PROVIDER_URL=https://polygon-mumbai-bor.publicnode.com
# We provide here some defaults, but we encourage you to choose your own.
ENCRYPTOR_PRIVATE_KEY=0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86
CONSUMER_PRIVATE_KEY=0xf307e165339cb5deb2b8ec59c31a5c0a957b8e8453ce7fe8a19d9a4c8acf36d4
+RITUAL_ID=5
+DOMAIN=tapir
diff --git a/examples/taco/nodejs/src/index.ts b/examples/taco/nodejs/src/index.ts
index 98f5960b7..ea2262605 100644
--- a/examples/taco/nodejs/src/index.ts
+++ b/examples/taco/nodejs/src/index.ts
@@ -32,10 +32,13 @@ if (!consumerPrivateKey) {
throw new Error('CONSUMER_PRIVATE_KEY is not set.');
}
-const domain = domains.DEVNET;
-const ritualId = 0; // Replace with your own ritual ID
+const domain = process.env.DOMAIN || domains.TESTNET;
+const ritualId = parseInt(process.env.RITUAL_ID || "5");
const provider = new ethers.providers.JsonRpcProvider(rpcProviderUrl);
+console.log('Domain:', domain);
+console.log('Ritual ID:', ritualId);
+
const encryptToBytes = async (messageString: string) => {
const encryptorSigner = new ethers.Wallet(encryptorPrivateKey);
console.log(
From 70b579428dde8b257e4ac9a88c11e752d8bea415 Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Thu, 21 Dec 2023 14:37:09 +0100
Subject: [PATCH 4/5] chore(ci): add a tapir ci job
---
.github/workflows/lynx.yml | 19 ++++++-------
.github/workflows/tapir.yml | 56 +++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 10 deletions(-)
create mode 100644 .github/workflows/tapir.yml
diff --git a/.github/workflows/lynx.yml b/.github/workflows/lynx.yml
index 3a7730d5b..d61d89321 100644
--- a/.github/workflows/lynx.yml
+++ b/.github/workflows/lynx.yml
@@ -4,19 +4,17 @@ on:
schedule:
- cron: "0 * * * *" # Every hour
pull_request:
- # branches:
- # - main
- # - development
- # - epic-*
workflow_dispatch:
-env: # TODO: Use variables when GH supports it for forks. See https://github.com/orgs/community/discussions/44322
+# TODO: Use variables when GH supports it for forks. See https://github.com/orgs/community/discussions/44322
+env:
RPC_PROVIDER_URL: "https://polygon-mumbai.infura.io/v3/3747007a284045d483c342fb39889a30"
ENCRYPTOR_PRIVATE_KEY: "0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86"
CONSUMER_PRIVATE_KEY: "0xf307e165339cb5deb2b8ec59c31a5c0a957b8e8453ce7fe8a19d9a4c8acf36d4"
+ RITUAL_ID: "0"
jobs:
- build_project:
+ networks:
name: '🔎 Lynx Testnet Example on Node ${{ matrix.node }} and ${{ matrix.os }}'
runs-on: ${{ matrix.os }}
@@ -37,19 +35,20 @@ jobs:
node-version: ${{ matrix.node }}
cache: 'pnpm'
- - name: Lynx testnet node-js script installation
+ - name: Install dependencies
working-directory: ./examples/taco/nodejs
run: pnpm install
- - name: Lynx testnet node-js script environment
+ - name: Setup environment
working-directory: ./examples/taco/nodejs
# TODO: Use variables when GH supports it for forks. See https://github.com/orgs/community/discussions/44322
run: |
echo RPC_PROVIDER_URL=$RPC_PROVIDER_URL > .env
echo ENCRYPTOR_PRIVATE_KEY=$ENCRYPTOR_PRIVATE_KEY >> .env
echo CONSUMER_PRIVATE_KEY=$CONSUMER_PRIVATE_KEY >> .env
+ echo RITUAL_ID=$RITUAL_ID >> .env
+ echo DOMAIN=lynx >> .env
- - name: Lynx testnet node-js script execution
- id: lynx_script
+ - name: Run taco/nodejs script
working-directory: ./examples/taco/nodejs
run: pnpm start
diff --git a/.github/workflows/tapir.yml b/.github/workflows/tapir.yml
new file mode 100644
index 000000000..cfde35683
--- /dev/null
+++ b/.github/workflows/tapir.yml
@@ -0,0 +1,56 @@
+name: '🔎 Tapir Testnet Example'
+
+on:
+ schedule:
+ - cron: "0 * * * *" # Every hour
+ pull_request:
+ branches:
+ - main
+ workflow_dispatch:
+
+# TODO: Use variables when GH supports it for forks. See https://github.com/orgs/community/discussions/44322
+env:
+ RPC_PROVIDER_URL: "https://polygon-mumbai.infura.io/v3/3747007a284045d483c342fb39889a30"
+ ENCRYPTOR_PRIVATE_KEY: "0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86"
+ CONSUMER_PRIVATE_KEY: "0xf307e165339cb5deb2b8ec59c31a5c0a957b8e8453ce7fe8a19d9a4c8acf36d4"
+ RITUAL_ID: "5"
+
+jobs:
+ networks:
+ name: '🔎 Tapir Testnet Example on Node ${{ matrix.node }} and ${{ matrix.os }}'
+
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ node: [ '18.x' ]
+ os: [ ubuntu-latest ]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: pnpm/action-setup@v2
+ with:
+ version: 8.1
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node }}
+ cache: 'pnpm'
+
+ - name: Install dependencies
+ working-directory: ./examples/taco/nodejs
+ run: pnpm install
+
+ - name: Setup environment
+ working-directory: ./examples/taco/nodejs
+ # TODO: Use variables when GH supports it for forks. See https://github.com/orgs/community/discussions/44322
+ run: |
+ echo RPC_PROVIDER_URL=$RPC_PROVIDER_URL > .env
+ echo ENCRYPTOR_PRIVATE_KEY=$ENCRYPTOR_PRIVATE_KEY >> .env
+ echo CONSUMER_PRIVATE_KEY=$CONSUMER_PRIVATE_KEY >> .env
+ echo RITUAL_ID=$RITUAL_ID >> .env
+ echo DOMAIN=tapir >> .env
+
+ - name: Run taco/nodejs script
+ working-directory: ./examples/taco/nodejs
+ run: pnpm start
From 1fb32bdbb230c5ead930a558ef7127e0faba0d11 Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Thu, 21 Dec 2023 15:13:04 +0100
Subject: [PATCH 5/5] feature: migrate from ethers to viem (wip)
---
.eslintignore | 2 +
demos/taco-demo/package.json | 9 +-
demos/taco-demo/src/App.tsx | 36 +-
demos/taco-demo/src/react-app-env.d.ts | 5 -
demos/taco-demo/webpack.config.js | 4 +-
demos/taco-nft-demo/package.json | 9 +-
demos/taco-nft-demo/src/App.tsx | 33 +-
demos/taco-nft-demo/src/react-app-env.d.ts | 5 -
demos/taco-nft-demo/webpack.config.js | 4 +-
examples/pre/nextjs/package.json | 6 +
examples/pre/nextjs/src/app/page.tsx | 35 +-
examples/pre/nodejs/package.json | 6 +-
examples/pre/nodejs/src/index.ts | 17 +-
examples/pre/react/package.json | 2 +-
examples/pre/react/src/App.tsx | 27 +-
examples/pre/react/src/react-app-env.d.ts | 8 -
examples/pre/webpack-5/package.json | 6 +-
examples/pre/webpack-5/src/index.ts | 26 +-
examples/taco/nextjs/package.json | 14 +-
examples/taco/nextjs/src/app/layout.tsx | 2 +-
examples/taco/nextjs/src/app/page.tsx | 113 ++--
examples/taco/nextjs/src/hooks/useTaco.ts | 35 +-
examples/taco/nodejs/README.md | 7 +-
examples/taco/nodejs/package.json | 6 +-
examples/taco/nodejs/src/index.ts | 58 +-
examples/taco/react/package.json | 6 +-
examples/taco/react/src/App.tsx | 112 ++--
examples/taco/react/src/hooks/useTaco.ts | 39 +-
examples/taco/react/src/index.tsx | 2 +-
examples/taco/react/src/react-app-env.d.ts | 8 -
examples/taco/webpack-5/package.json | 7 +-
examples/taco/webpack-5/src/index.html | 3 +-
examples/taco/webpack-5/src/index.ts | 27 +-
packages/pre/package.json | 3 +-
packages/pre/src/characters/alice.ts | 34 +-
packages/pre/src/policy.ts | 27 +-
.../pre/test/acceptance/alice-grants.test.ts | 6 +-
.../pre/test/acceptance/delay-enact.test.ts | 9 +-
packages/shared/package.json | 3 +-
.../src/contracts/agents/coordinator.ts | 64 +-
.../src/contracts/agents/global-allow-list.ts | 44 +-
.../contracts/agents/subscription-manager.ts | 57 +-
packages/shared/src/index.ts | 1 +
packages/shared/src/utils.ts | 1 -
packages/shared/src/viem.ts | 69 ++
packages/taco/examples/encrypt-decrypt.ts | 35 +-
packages/taco/package.json | 5 +-
.../taco/src/conditions/condition-expr.ts | 10 +-
.../taco/src/conditions/context/context.ts | 29 +-
.../taco/src/conditions/context/providers.ts | 117 ++--
packages/taco/src/dkg.ts | 35 +-
packages/taco/src/taco.ts | 64 +-
packages/taco/src/tdec.ts | 35 +-
packages/taco/src/web3.ts | 25 -
.../test/conditions/base/contract.test.ts | 4 +-
.../taco/test/conditions/conditions.test.ts | 10 +-
packages/taco/test/conditions/context.test.ts | 48 +-
packages/taco/test/dkg-client.test.ts | 10 +-
packages/taco/test/taco.test.ts | 15 +-
packages/taco/test/test-utils.ts | 4 +-
packages/test-utils/package.json | 1 +
packages/test-utils/src/index.ts | 2 +
packages/test-utils/src/utils.ts | 52 +-
packages/test-utils/src/viem.ts | 18 +
pnpm-lock.yaml | 634 ++++++++++++++++--
tsconfig.json | 3 +-
66 files changed, 1447 insertions(+), 706 deletions(-)
delete mode 100644 demos/taco-demo/src/react-app-env.d.ts
delete mode 100644 demos/taco-nft-demo/src/react-app-env.d.ts
delete mode 100644 examples/pre/react/src/react-app-env.d.ts
delete mode 100644 examples/taco/react/src/react-app-env.d.ts
create mode 100644 packages/shared/src/viem.ts
delete mode 100644 packages/taco/src/web3.ts
create mode 100644 packages/test-utils/src/viem.ts
diff --git a/.eslintignore b/.eslintignore
index dd449725e..17ab736c5 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1 +1,3 @@
*.md
+**/dist/**
+**/build/**
diff --git a/demos/taco-demo/package.json b/demos/taco-demo/package.json
index 615b81ae9..d775733ba 100644
--- a/demos/taco-demo/package.json
+++ b/demos/taco-demo/package.json
@@ -9,7 +9,9 @@
"build": "pnpm clean && webpack --mode production --progress",
"clean": "rimraf build",
"check": "pnpm type-check && pnpm build",
- "type-check": "tsc --noEmit"
+ "type-check": "tsc --noEmit",
+ "lint": "eslint --ext .ts src",
+ "lint:fix": "pnpm lint --fix"
},
"dependencies": {
"@nucypher/taco": "^0.1.0-rc.6",
@@ -21,7 +23,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",
@@ -34,7 +37,7 @@
"react-refresh": "^0.14.0",
"rimraf": "^5.0.5",
"stream-browserify": "^3.0.0",
- "typescript": "^4.8.3",
+ "typescript": "^5.2.2",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.11.1"
diff --git a/demos/taco-demo/src/App.tsx b/demos/taco-demo/src/App.tsx
index 0329df38b..087a19255 100644
--- a/demos/taco-demo/src/App.tsx
+++ b/demos/taco-demo/src/App.tsx
@@ -8,14 +8,16 @@ import {
ThresholdMessageKit,
} from '@nucypher/taco';
import { Mumbai, useEthers } from '@usedapp/core';
-import { ethers } from 'ethers';
import React, { useEffect, useState } from 'react';
+import 'viem/window';
+
+import { createPublicClient, createWalletClient, custom } from 'viem';
import { ConditionBuilder } from './ConditionBuilder';
+import { DEFAULT_DOMAIN, DEFAULT_RITUAL_ID } from './config';
import { Decrypt } from './Decrypt';
import { Encrypt } from './Encrypt';
import { Spinner } from './Spinner';
-import { DEFAULT_DOMAIN, DEFAULT_RITUAL_ID } from './config';
export default function App() {
const { activateBrowserWallet, deactivate, account, switchNetwork } =
@@ -36,6 +38,10 @@ export default function App() {
}, []);
const encryptMessage = async (message: string) => {
+ if (!window.ethereum) {
+ console.error('You need to connect to your wallet first');
+ return;
+ }
if (!condition) {
return;
}
@@ -43,14 +49,19 @@ export default function App() {
await switchNetwork(Mumbai.chainId);
- const provider = new ethers.providers.Web3Provider(window.ethereum);
+ const publicClient = createPublicClient({
+ transport: custom(window.ethereum),
+ });
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
const encryptedMessage = await encrypt(
- provider,
+ publicClient,
domain,
message,
condition,
ritualId,
- provider.getSigner(),
+ walletClient,
);
setEncryptedMessage(encryptedMessage);
@@ -58,6 +69,10 @@ export default function App() {
};
const decryptMessage = async (encryptedMessage: ThresholdMessageKit) => {
+ if (!window.ethereum) {
+ console.error('You need to connect to your wallet first');
+ return;
+ }
if (!condition) {
return;
}
@@ -65,13 +80,18 @@ export default function App() {
setDecryptedMessage('');
setDecryptionErrors([]);
- const provider = new ethers.providers.Web3Provider(window.ethereum);
+ const publicClient = createPublicClient({
+ transport: custom(window.ethereum),
+ });
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
const decryptedMessage = await decrypt(
- provider,
+ publicClient,
domain,
encryptedMessage,
getPorterUri(domain),
- provider.getSigner(),
+ walletClient,
);
setDecryptedMessage(new TextDecoder().decode(decryptedMessage));
diff --git a/demos/taco-demo/src/react-app-env.d.ts b/demos/taco-demo/src/react-app-env.d.ts
deleted file mode 100644
index 4e39a38ad..000000000
--- a/demos/taco-demo/src/react-app-env.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-///
-
-interface Window {
- ethereum: any;
-}
diff --git a/demos/taco-demo/webpack.config.js b/demos/taco-demo/webpack.config.js
index 11c98381e..9bbd7185b 100644
--- a/demos/taco-demo/webpack.config.js
+++ b/demos/taco-demo/webpack.config.js
@@ -33,8 +33,8 @@ module.exports = {
DEFAULT_RITUAL_ID: JSON.stringify(process.env.DEFAULT_RITUAL_ID),
DEFAULT_DOMAIN: JSON.stringify(process.env.DEFAULT_DOMAIN),
},
- }
- })
+ },
+ }),
].filter(Boolean),
module: {
rules: [
diff --git a/demos/taco-nft-demo/package.json b/demos/taco-nft-demo/package.json
index 1b7c07e08..2ed6ae059 100644
--- a/demos/taco-nft-demo/package.json
+++ b/demos/taco-nft-demo/package.json
@@ -9,7 +9,9 @@
"build": "pnpm clean && webpack --mode production --progress",
"clean": "rimraf build",
"check": "pnpm type-check && pnpm build",
- "type-check": "tsc --noEmit"
+ "type-check": "tsc --noEmit",
+ "lint": "eslint --ext .ts src",
+ "lint:fix": "pnpm lint --fix"
},
"dependencies": {
"@nucypher/taco": "^0.1.0-rc.6",
@@ -21,7 +23,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",
@@ -34,7 +37,7 @@
"react-refresh": "^0.14.0",
"rimraf": "^5.0.5",
"stream-browserify": "^3.0.0",
- "typescript": "^4.8.3",
+ "typescript": "^5.2.2",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.11.1"
diff --git a/demos/taco-nft-demo/src/App.tsx b/demos/taco-nft-demo/src/App.tsx
index c4928f8e5..1ecf960c8 100644
--- a/demos/taco-nft-demo/src/App.tsx
+++ b/demos/taco-nft-demo/src/App.tsx
@@ -8,8 +8,9 @@ import {
ThresholdMessageKit,
} from '@nucypher/taco';
import { Mumbai, useEthers } from '@usedapp/core';
-import { ethers } from 'ethers';
import React, { useEffect, useState } from 'react';
+import 'viem/window';
+import { createPublicClient, createWalletClient, custom } from 'viem';
import { Decrypt } from './Decrypt';
import { Encrypt } from './Encrypt';
@@ -35,6 +36,10 @@ export default function App() {
}, []);
const encryptMessage = async (message: string) => {
+ if (!window.ethereum) {
+ console.error('You need to connect to your wallet first');
+ return;
+ }
if (!condition) {
return;
}
@@ -42,14 +47,19 @@ export default function App() {
await switchNetwork(Mumbai.chainId);
- const provider = new ethers.providers.Web3Provider(window.ethereum);
+ const publicClient = createPublicClient({
+ transport: custom(window.ethereum),
+ });
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
const encryptedMessage = await encrypt(
- provider,
+ publicClient,
domain,
message,
condition,
ritualId,
- provider.getSigner(),
+ walletClient,
);
setEncryptedMessage(encryptedMessage);
@@ -57,6 +67,10 @@ export default function App() {
};
const decryptMessage = async (encryptedMessage: ThresholdMessageKit) => {
+ if (!window.ethereum) {
+ console.error('You need to connect to your wallet first');
+ return;
+ }
if (!condition) {
return;
}
@@ -64,13 +78,18 @@ export default function App() {
setDecryptedMessage('');
setDecryptionErrors([]);
- const provider = new ethers.providers.Web3Provider(window.ethereum);
+ const publicClient = createPublicClient({
+ transport: custom(window.ethereum),
+ });
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
const decryptedMessage = await decrypt(
- provider,
+ publicClient,
domain,
encryptedMessage,
getPorterUri(domain),
- provider.getSigner(),
+ walletClient,
);
setDecryptedMessage(new TextDecoder().decode(decryptedMessage));
diff --git a/demos/taco-nft-demo/src/react-app-env.d.ts b/demos/taco-nft-demo/src/react-app-env.d.ts
deleted file mode 100644
index 4e39a38ad..000000000
--- a/demos/taco-nft-demo/src/react-app-env.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-///
-
-interface Window {
- ethereum: any;
-}
diff --git a/demos/taco-nft-demo/webpack.config.js b/demos/taco-nft-demo/webpack.config.js
index 11c98381e..9bbd7185b 100644
--- a/demos/taco-nft-demo/webpack.config.js
+++ b/demos/taco-nft-demo/webpack.config.js
@@ -33,8 +33,8 @@ module.exports = {
DEFAULT_RITUAL_ID: JSON.stringify(process.env.DEFAULT_RITUAL_ID),
DEFAULT_DOMAIN: JSON.stringify(process.env.DEFAULT_DOMAIN),
},
- }
- })
+ },
+ }),
].filter(Boolean),
module: {
rules: [
diff --git a/examples/pre/nextjs/package.json b/examples/pre/nextjs/package.json
index a9779d02b..38345be18 100644
--- a/examples/pre/nextjs/package.json
+++ b/examples/pre/nextjs/package.json
@@ -11,6 +11,12 @@
},
"dependencies": {
"@nucypher/pre": "workspace:*",
+ "next": "14.0.3",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "viem": "^1.19.9"
+ },
+ "devDependencies": {
"@types/node": "20.10.0",
"@types/react": "18.2.45",
"@types/react-dom": "18.2.14",
diff --git a/examples/pre/nextjs/src/app/page.tsx b/examples/pre/nextjs/src/app/page.tsx
index 772dfe070..8e7fd4666 100644
--- a/examples/pre/nextjs/src/app/page.tsx
+++ b/examples/pre/nextjs/src/app/page.tsx
@@ -9,18 +9,13 @@ import {
SecretKey,
toHexString,
} from '@nucypher/pre';
-import { ethers } from 'ethers';
-import { hexlify } from "ethers/lib/utils";
import { useEffect, useState } from 'react';
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-declare const window: any;
+import { createWalletClient, custom, toHex, WalletClient } from 'viem';
+import 'viem/window';
function App() {
const [isInit, setIsInit] = useState(false);
- const [provider, setProvider] = useState<
- ethers.providers.Web3Provider | undefined
- >();
+ const [walletClient, setWalletClient] = useState();
const [alice, setAlice] = useState();
const [bob, setBob] = useState();
const [policy, setPolicy] = useState();
@@ -30,32 +25,33 @@ function App() {
setIsInit(true);
};
- const loadWeb3Provider = async () => {
+ const loadWalletClient = async () => {
if (!window.ethereum) {
console.error('You need to connect to your wallet first');
+ return;
}
- const provider = new ethers.providers.Web3Provider(window.ethereum, 'any');
-
- const { chainId } = await provider.getNetwork();
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
+ const chainId = await walletClient.getChainId();
const mumbaiChainId = 80001;
if (chainId !== mumbaiChainId) {
// Switch to Polygon Mumbai testnet
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
- params: [{ chainId: hexlify(mumbaiChainId) }],
+ params: [{ chainId: toHex(mumbaiChainId) }],
});
}
- await provider.send('eth_requestAccounts', []);
- setProvider(provider);
+ setWalletClient(walletClient);
};
useEffect(() => {
initNucypher();
- loadWeb3Provider();
+ loadWalletClient();
}, []);
- if (!isInit || !provider) {
+ if (!isInit || !walletClient) {
return Loading...
;
}
@@ -82,7 +78,7 @@ function App() {
const getRandomLabel = () => `label-${new Date().getTime()}`;
const runExample = async () => {
- if (!provider) {
+ if (!walletClient) {
console.error('You need to connect to your wallet first');
return;
}
@@ -106,8 +102,7 @@ function App() {
endDate,
};
const policy = await alice.grant(
- provider,
- provider.getSigner(),
+ walletClient,
domains.TESTNET,
getPorterUri(domains.TESTNET),
policyParams,
diff --git a/examples/pre/nodejs/package.json b/examples/pre/nodejs/package.json
index 35a479f94..950380e62 100644
--- a/examples/pre/nodejs/package.json
+++ b/examples/pre/nodejs/package.json
@@ -11,7 +11,9 @@
},
"dependencies": {
"@nucypher/pre": "workspace:*",
- "dotenv": "^16.3.1",
- "ethers": "^5.7.2"
+ "viem": "^1.19.9"
+ },
+ "devDependencies": {
+ "dotenv": "^16.3.1"
}
}
diff --git a/examples/pre/nodejs/src/index.ts b/examples/pre/nodejs/src/index.ts
index c684fdf10..7f131a0e3 100644
--- a/examples/pre/nodejs/src/index.ts
+++ b/examples/pre/nodejs/src/index.ts
@@ -8,7 +8,8 @@ import {
toBytes,
} from '@nucypher/pre';
import * as dotenv from 'dotenv';
-import { ethers } from 'ethers';
+import { createWalletClient, Hex, http } from 'viem';
+import { privateKeyToAccount } from 'viem/accounts';
dotenv.config();
@@ -49,15 +50,18 @@ const getRandomLabel = () => `label-${new Date().getTime()}`;
const runExample = async () => {
await initialize();
- const provider = new ethers.providers.JsonRpcProvider(rpcProviderUrl);
+ const account = privateKeyToAccount(privateKey);
+ const walletClient = createWalletClient({
+ transport: http(rpcProviderUrl),
+ account,
+ });
// Make sure the provider is connected to Mumbai testnet
- const network = await provider.getNetwork();
- if (network.chainId !== 80001) {
+ const chainId = await walletClient.getChainId();
+ if (chainId !== 80001) {
console.error('Please connect to Mumbai testnet');
}
- const signer = new ethers.Wallet(privateKey);
const policyParams = {
bob: makeRemoteBob(),
label: getRandomLabel(),
@@ -70,8 +74,7 @@ const runExample = async () => {
console.log('Creating policy...');
const policy = await alice.grant(
- provider,
- signer,
+ walletClient,
domains.TESTNET,
getPorterUri(domains.TESTNET),
policyParams,
diff --git a/examples/pre/react/package.json b/examples/pre/react/package.json
index f4d540117..b21b51404 100644
--- a/examples/pre/react/package.json
+++ b/examples/pre/react/package.json
@@ -26,7 +26,7 @@
"@nucypher/pre": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "ethers": "^5.7.2"
+ "viem": "^1.19.9"
},
"devDependencies": {
"@types/node": "^20.10.0",
diff --git a/examples/pre/react/src/App.tsx b/examples/pre/react/src/App.tsx
index 3bd6c2bc5..47174c8d4 100644
--- a/examples/pre/react/src/App.tsx
+++ b/examples/pre/react/src/App.tsx
@@ -8,15 +8,13 @@ import {
SecretKey,
toHexString,
} from '@nucypher/pre';
-import { ethers } from 'ethers';
-import { hexlify } from "ethers/lib/utils";
import { useEffect, useState } from 'react';
+import { createWalletClient, custom, toHex, WalletClient } from 'viem';
+import 'viem/window';
function App() {
const [isInit, setIsInit] = useState(false);
- const [provider, setProvider] = useState<
- ethers.providers.Web3Provider | undefined
- >();
+ const [walletClient, setWalletClient] = useState();
const [alice, setAlice] = useState();
const [bob, setBob] = useState();
const [policy, setPolicy] = useState();
@@ -29,21 +27,23 @@ function App() {
const loadWeb3Provider = async () => {
if (!window.ethereum) {
console.error('You need to connect to your wallet first');
+ return;
}
- const provider = new ethers.providers.Web3Provider(window.ethereum, 'any');
- const { chainId } = await provider.getNetwork();
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
+ const chainId = await walletClient.getChainId();
const mumbaiChainId = 80001;
if (chainId !== mumbaiChainId) {
// Switch to Polygon Mumbai testnet
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
- params: [{ chainId: hexlify(mumbaiChainId) }],
+ params: [{ chainId: toHex(mumbaiChainId) }],
});
}
- await provider.send('eth_requestAccounts', []);
- setProvider(provider);
+ setWalletClient(walletClient);
};
useEffect(() => {
@@ -51,7 +51,7 @@ function App() {
loadWeb3Provider();
}, []);
- if (!isInit || !provider) {
+ if (!isInit || !walletClient) {
return Loading...
;
}
@@ -78,7 +78,7 @@ function App() {
const getRandomLabel = () => `label-${new Date().getTime()}`;
const runExample = async () => {
- if (!provider) {
+ if (!walletClient) {
console.error('You need to connect to your wallet first');
return;
}
@@ -102,8 +102,7 @@ function App() {
endDate,
};
const policy = await alice.grant(
- provider,
- provider.getSigner(),
+ walletClient,
domains.TESTNET,
getPorterUri(domains.TESTNET),
policyParams,
diff --git a/examples/pre/react/src/react-app-env.d.ts b/examples/pre/react/src/react-app-env.d.ts
deleted file mode 100644
index 8f8826530..000000000
--- a/examples/pre/react/src/react-app-env.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-import { ExternalProvider } from '@ethersproject/providers';
-
-declare global {
- interface Window {
- ethereum?: ExternalProvider;
- }
-}
diff --git a/examples/pre/webpack-5/package.json b/examples/pre/webpack-5/package.json
index 5b863ae07..e37ac44a0 100644
--- a/examples/pre/webpack-5/package.json
+++ b/examples/pre/webpack-5/package.json
@@ -12,14 +12,14 @@
"type-check": "tsc"
},
"dependencies": {
- "@nucypher/pre": "workspace:*"
+ "@nucypher/pre": "workspace:*",
+ "viem": "^1.19.9"
},
"devDependencies": {
"copy-webpack-plugin": "^11.0.0",
"esbuild-loader": "^2.11.0",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
- "webpack-dev-server": "^4.7.4",
- "ethers": "^5.7.2"
+ "webpack-dev-server": "^4.7.4"
}
}
diff --git a/examples/pre/webpack-5/src/index.ts b/examples/pre/webpack-5/src/index.ts
index eb555dc06..fac8ada2f 100644
--- a/examples/pre/webpack-5/src/index.ts
+++ b/examples/pre/webpack-5/src/index.ts
@@ -6,14 +6,8 @@ import {
initialize,
SecretKey,
} from '@nucypher/pre';
-import { ethers } from 'ethers';
-import { hexlify } from 'ethers/lib/utils';
-
-declare global {
- interface Window {
- ethereum?: ethers.providers.ExternalProvider;
- }
-}
+import { createWalletClient, custom, toHex } from 'viem';
+import 'viem/window';
const txtEncoder = new TextEncoder();
@@ -44,22 +38,23 @@ const getRandomLabel = () => `label-${new Date().getTime()}`;
const runExample = async () => {
if (!window.ethereum) {
console.error('You need to connect to your wallet first');
+ return;
}
await initialize();
alert('Sign a transaction to create a policy.');
- const provider = new ethers.providers.Web3Provider(window.ethereum!, 'any');
- await provider.send('eth_requestAccounts', []);
-
- const { chainId } = await provider.getNetwork();
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
+ const chainId = await walletClient.getChainId();
const mumbaiChainId = 80001;
if (chainId !== mumbaiChainId) {
// Switch to Polygon Mumbai testnet
- await window.ethereum!.request!({
+ await window.ethereum.request!({
method: 'wallet_switchEthereumChain',
- params: [{ chainId: hexlify(mumbaiChainId) }],
+ params: [{ chainId: toHex(mumbaiChainId) }],
});
}
@@ -79,8 +74,7 @@ const runExample = async () => {
const alice = makeAlice();
const policy = await alice.grant(
- provider,
- provider.getSigner(),
+ walletClient,
domains.TESTNET,
getPorterUri(domains.TESTNET),
policyParams,
diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json
index 7c1862f74..d1abc04f0 100644
--- a/examples/taco/nextjs/package.json
+++ b/examples/taco/nextjs/package.json
@@ -12,15 +12,21 @@
"dependencies": {
"@nucypher/shared": "workspace:*",
"@nucypher/taco": "workspace:*",
- "@types/node": "20.10.0",
+ "@types/node": "20.6.3",
"@types/react": "18.2.45",
"@types/react-dom": "18.2.14",
- "eslint": "8.54.0",
+ "eslint": "8.53.0",
"eslint-config-next": "14.0.3",
- "ethers": "^5.7.2",
"next": "14.0.4",
"react": "18.2.0",
"react-dom": "18.2.0",
- "typescript": "5.2.2"
+ "viem": "^1.19.9"
+ },
+ "devDependencies": {
+ "@types/node": "20.10.0",
+ "@types/react": "18.2.37",
+ "@types/react-dom": "18.2.14",
+ "eslint": "8.54.0",
+ "eslint-config-next": "14.0.3"
}
}
diff --git a/examples/taco/nextjs/src/app/layout.tsx b/examples/taco/nextjs/src/app/layout.tsx
index a048075ad..f00aeecb5 100644
--- a/examples/taco/nextjs/src/app/layout.tsx
+++ b/examples/taco/nextjs/src/app/layout.tsx
@@ -1,6 +1,6 @@
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
-import '../../styles/global.css'
+import '../../styles/global.css';
const inter = Inter({ subsets: ['latin'] });
diff --git a/examples/taco/nextjs/src/app/page.tsx b/examples/taco/nextjs/src/app/page.tsx
index a9530033a..f16fd5c7b 100644
--- a/examples/taco/nextjs/src/app/page.tsx
+++ b/examples/taco/nextjs/src/app/page.tsx
@@ -1,30 +1,29 @@
'use client';
-import {fromHexString} from "@nucypher/shared";
-import {conditions, domains, fromBytes, toHexString} from '@nucypher/taco';
-import {ethers} from 'ethers';
-import {hexlify} from 'ethers/lib/utils';
-import {useEffect, useState} from 'react';
+import { fromHexString } from '@nucypher/shared';
+import { conditions, domains, fromBytes, toHexString } from '@nucypher/taco';
+import { useEffect, useState } from 'react';
+import 'viem/window';
+import {
+ createPublicClient,
+ createWalletClient,
+ custom,
+ PublicClient,
+ toHex,
+ WalletClient,
+} from 'viem';
import useTaco from '../hooks/useTaco';
-
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-declare const window: any;
-
const ritualId = 5; // Replace with your own ritual ID
const domain = domains.TESTNET;
function App() {
- const [provider, setProvider] = useState<
- ethers.providers.Web3Provider | undefined
- >();
- const [message, setMessage] = useState('this is a secret')
- const [encrypting, setEncrypting] = useState(false)
- const [encryptedText, setEncryptedText] = useState(
- '',
- );
- const [decrypting, setDecrypting] = useState(false)
+ const [walletClient, setWalletClient] = useState();
+ const [publicClient, setPublicClient] = useState();
+ const [message, setMessage] = useState('this is a secret');
+ const [encrypting, setEncrypting] = useState(false);
+ const [encryptedText, setEncryptedText] = useState('');
+ const [decrypting, setDecrypting] = useState(false);
const [decryptedMessage, setDecryptedMessage] = useState(
'',
);
@@ -32,21 +31,28 @@ function App() {
const loadWeb3Provider = async () => {
if (!window.ethereum) {
console.error('You need to connect to your wallet first');
+ return;
}
- const provider = new ethers.providers.Web3Provider(window.ethereum, 'any');
- const { chainId } = await provider.getNetwork();
+ const publicClient = createPublicClient({
+ transport: custom(window.ethereum),
+ });
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
+
+ const chainId = await walletClient.getChainId();
const mumbaiChainId = 80001;
if (chainId !== mumbaiChainId) {
// Switch to Polygon Mumbai testnet
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
- params: [{ chainId: hexlify(mumbaiChainId) }],
+ params: [{ chainId: toHex(mumbaiChainId) }],
});
}
- await provider.send('eth_requestAccounts', []);
- setProvider(provider);
+ setWalletClient(walletClient);
+ setPublicClient(publicClient);
};
useEffect(() => {
@@ -55,19 +61,21 @@ function App() {
const { isInit, encryptDataToBytes, decryptDataFromBytes } = useTaco({
domain,
- provider,
ritualId,
+ walletClient,
+ publicClient,
});
- if (!isInit || !provider) {
+ if (!isInit || !walletClient) {
return Loading...
;
}
const encryptMessage = async () => {
- if(!provider) return;
- setEncrypting(true)
+ if (!walletClient) {
+ return;
+ }
+ setEncrypting(true);
try {
- const signer = provider.getSigner();
const hasPositiveBalance = new conditions.RpcCondition({
chain: 80001,
method: 'eth_getBalance',
@@ -82,41 +90,60 @@ function App() {
const encryptedBytes = await encryptDataToBytes(
message,
hasPositiveBalance,
- signer,
+ publicClient,
+ walletClient,
);
if (encryptedBytes) {
- setEncryptedText(toHexString(encryptedBytes))
+ setEncryptedText(toHexString(encryptedBytes));
}
} catch (e) {
- console.log(e)
+ console.log(e);
}
- setEncrypting(false)
- }
+ setEncrypting(false);
+ };
const decryptMessage = async () => {
- if(!encryptedText || !provider) return
+ if (!encryptedText || !walletClient || !publicClient) {
+ return;
+ }
try {
- setDecrypting(true)
- const signer = provider.getSigner();
-
+ setDecrypting(true);
console.log('Decrypting message...');
const decryptedMessage = await decryptDataFromBytes(
fromHexString(encryptedText),
- signer,
+ publicClient,
+ walletClient,
);
if (decryptedMessage) {
setDecryptedMessage(fromBytes(decryptedMessage));
}
} catch (e) {
- console.log(e)
+ console.log(e);
}
- setDecrypting(false)
+ setDecrypting(false);
};
return (
-
Secret message: setMessage(e.target.value)} onClick={encryptMessage}/> {encrypting && 'Encrypting...'}
- Encrypted message: setEncryptedText(e.target.value)} /> {decrypting && 'Decrypting...'}
+
+ Secret message:{' '}
+ setMessage(e.target.value)}
+ onClick={encryptMessage}
+ />
+
+ {encrypting && 'Encrypting...'}
+
+
+ Encrypted message:{' '}
+ setEncryptedText(e.target.value)}
+ />
+
+ {decrypting && 'Decrypting...'}
+
{decryptedMessage && Decrypted message: {decryptedMessage}
}
);
diff --git a/examples/taco/nextjs/src/hooks/useTaco.ts b/examples/taco/nextjs/src/hooks/useTaco.ts
index be78a7bb5..653a15005 100644
--- a/examples/taco/nextjs/src/hooks/useTaco.ts
+++ b/examples/taco/nextjs/src/hooks/useTaco.ts
@@ -7,17 +7,17 @@ import {
initialize,
ThresholdMessageKit,
} from '@nucypher/taco';
-import { ethers } from 'ethers';
import { useCallback, useEffect, useState } from 'react';
+import { PublicClient, WalletClient } from 'viem';
export default function useTaco({
ritualId,
domain,
- provider,
}: {
ritualId: number;
domain: Domain;
- provider: ethers.providers.Provider | undefined;
+ publicClient?: PublicClient;
+ walletClient?: WalletClient;
}) {
const [isInit, setIsInit] = useState(false);
@@ -26,38 +26,47 @@ export default function useTaco({
}, []);
const decryptDataFromBytes = useCallback(
- async (encryptedBytes: Uint8Array, signer?: ethers.Signer) => {
- if (!isInit || !provider) return;
+ async (
+ encryptedBytes: Uint8Array,
+ publicClient?: PublicClient,
+ walletClient?: WalletClient,
+ ) => {
+ if (!isInit || !publicClient || !walletClient) {
+ return;
+ }
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
return decrypt(
- provider,
+ publicClient,
domain,
messageKit,
getPorterUri(domain),
- signer,
+ walletClient,
);
},
- [isInit, provider, domain],
+ [isInit, domain],
);
const encryptDataToBytes = useCallback(
async (
message: string,
condition: conditions.Condition,
- encryptorSigner: ethers.Signer,
+ publicClient?: PublicClient,
+ walletClient?: WalletClient,
) => {
- if (!isInit || !provider) return;
+ if (!isInit || !publicClient || !walletClient) {
+ return;
+ }
const messageKit = await encrypt(
- provider,
+ publicClient,
domain,
message,
condition,
ritualId,
- encryptorSigner,
+ walletClient,
);
return messageKit.toBytes();
},
- [isInit, provider, domain, ritualId],
+ [isInit, domain, ritualId],
);
return {
diff --git a/examples/taco/nodejs/README.md b/examples/taco/nodejs/README.md
index a0a7578b8..9537598d3 100644
--- a/examples/taco/nodejs/README.md
+++ b/examples/taco/nodejs/README.md
@@ -10,7 +10,12 @@ This script needs 3 environment variables, that you can set in the `.env` file:
* `ENCRYPTOR_PRIVATE_KEY` and `CONSUMER_PRIVATE_KEY`: Hex-encoded private keys for the Encryptor and the Consumer,
respectively.
-Default values for these variables are provided in `.env.example`, so you can run:
+- `RPC_PROVIDER_URL`: For TACo testnet you should use a Polygon Mumbai endpoint.
+- `ENCRYPTOR_PRIVATE_KEY` and `CONSUMER_PRIVATE_KEY`: Hex-encoded private keys
+ for the Encryptor and the Consumer, respectively.
+
+Default values for these variables are provided in `.env.example`, so you can
+run:
```bash
cp .env.example .env
diff --git a/examples/taco/nodejs/package.json b/examples/taco/nodejs/package.json
index ecf9cdb3b..6dc6085e4 100644
--- a/examples/taco/nodejs/package.json
+++ b/examples/taco/nodejs/package.json
@@ -11,7 +11,9 @@
},
"dependencies": {
"@nucypher/taco": "workspace:*",
- "dotenv": "^16.3.1",
- "ethers": "^5.7.2"
+ "viem": "^1.19.9"
+ },
+ "devDependencies": {
+ "dotenv": "^16.3.1"
}
}
diff --git a/examples/taco/nodejs/src/index.ts b/examples/taco/nodejs/src/index.ts
index ea2262605..3defb36d6 100644
--- a/examples/taco/nodejs/src/index.ts
+++ b/examples/taco/nodejs/src/index.ts
@@ -13,7 +13,9 @@ import {
toHexString,
} from '@nucypher/taco';
import * as dotenv from 'dotenv';
-import { ethers } from 'ethers';
+import { Hex, createPublicClient, createWalletClient, http } from 'viem';
+import { privateKeyToAccount } from 'viem/accounts';
+import { polygonMumbai } from 'viem/chains';
dotenv.config();
@@ -33,24 +35,44 @@ if (!consumerPrivateKey) {
}
const domain = process.env.DOMAIN || domains.TESTNET;
-const ritualId = parseInt(process.env.RITUAL_ID || "5");
-const provider = new ethers.providers.JsonRpcProvider(rpcProviderUrl);
+const ritualId = parseInt(process.env.RITUAL_ID || '5');
+
+const publicClient = createPublicClient({
+ transport: http(rpcProviderUrl),
+ chain: polygonMumbai,
+});
+
+const encryptorAccount = privateKeyToAccount(encryptorPrivateKey);
+const encryptorWalletClient = createWalletClient({
+ transport: http(rpcProviderUrl),
+ account: encryptorAccount,
+ chain: polygonMumbai,
+});
+
+const consumerAccount = privateKeyToAccount(consumerPrivateKey);
+const consumerWalletClient = createWalletClient({
+ transport: http(rpcProviderUrl),
+ account: consumerAccount,
+ chain: polygonMumbai,
+});
console.log('Domain:', domain);
console.log('Ritual ID:', ritualId);
const encryptToBytes = async (messageString: string) => {
- const encryptorSigner = new ethers.Wallet(encryptorPrivateKey);
- console.log(
- "Encryptor signer's address:",
- await encryptorSigner.getAddress(),
- );
+ // Make sure the provider is connected to Mumbai testnet
+ const chainId = await encryptorWalletClient.getChainId();
+ if (chainId !== polygonMumbai.id) {
+ console.error('Please connect to Mumbai testnet');
+ }
+
+ console.log("Encryptor signer's address:", encryptorAccount.address);
const message = toBytes(messageString);
console.log(format('Encrypting message ("%s") ...', messageString));
const hasPositiveBalance = new conditions.RpcCondition({
- chain: 80001,
+ chain: polygonMumbai.id,
method: 'eth_getBalance',
parameters: [':userAddress', 'latest'],
returnValueTest: {
@@ -64,39 +86,35 @@ const encryptToBytes = async (messageString: string) => {
);
const messageKit = await encrypt(
- provider,
+ publicClient,
domain,
message,
hasPositiveBalance,
ritualId,
- encryptorSigner,
+ encryptorWalletClient,
);
return messageKit.toBytes();
};
const decryptFromBytes = async (encryptedBytes: Uint8Array) => {
- const consumerSigner = new ethers.Wallet(consumerPrivateKey);
- console.log(
- "\nConsumer signer's address:",
- await consumerSigner.getAddress(),
- );
+ console.log("\nConsumer signer's address:", consumerAccount.address);
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
console.log('Decrypting message ...');
return decrypt(
- provider,
+ publicClient,
domain,
messageKit,
getPorterUri(domain),
- consumerSigner,
+ consumerWalletClient,
);
};
const runExample = async () => {
// Make sure the provider is connected to Mumbai testnet
- const network = await provider.getNetwork();
- if (network.chainId !== 80001) {
+ const chainId = await publicClient.getChainId();
+ if (chainId !== polygonMumbai.id) {
console.error('Please connect to Mumbai testnet');
}
await initialize();
diff --git a/examples/taco/react/package.json b/examples/taco/react/package.json
index 4085765a4..23d07c6b2 100644
--- a/examples/taco/react/package.json
+++ b/examples/taco/react/package.json
@@ -26,15 +26,13 @@
"@nucypher/shared": "workspace:*",
"@nucypher/taco": "workspace:*",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "viem": "^1.19.9"
},
"devDependencies": {
"@types/node": "^20.10.0",
"@types/react": "^18.2.45",
"@types/react-dom": "^18.2.14",
"react-scripts": "^5.0.1"
- },
- "peerDependencies": {
- "ethers": "^5.7.2"
}
}
diff --git a/examples/taco/react/src/App.tsx b/examples/taco/react/src/App.tsx
index 9820d7d65..2b83e6751 100644
--- a/examples/taco/react/src/App.tsx
+++ b/examples/taco/react/src/App.tsx
@@ -1,8 +1,14 @@
-import {fromHexString} from "@nucypher/shared";
-import {conditions, domains, fromBytes, toHexString} from '@nucypher/taco';
-import {ethers} from 'ethers';
-import {hexlify} from 'ethers/lib/utils';
-import {useEffect, useState} from 'react';
+import { fromHexString } from '@nucypher/shared';
+import { conditions, domains, fromBytes, toHexString } from '@nucypher/taco';
+import { useEffect, useState } from 'react';
+import {
+ createPublicClient,
+ createWalletClient,
+ custom,
+ PublicClient,
+ toHex,
+ WalletClient,
+} from 'viem';
import useTaco from './hooks/useTaco';
@@ -13,58 +19,65 @@ const ritualId = 5; // Replace with your own ritual ID
const domain = domains.TESTNET;
function App() {
- const [provider, setProvider] = useState<
- ethers.providers.Web3Provider | undefined
- >();
- const [message, setMessage] = useState('this is a secret')
- const [encrypting, setEncrypting] = useState(false)
- const [encryptedText, setEncryptedText] = useState(
- '',
- );
- const [decrypting, setDecrypting] = useState(false)
+ const [walletClient, setWalletClient] = useState();
+ const [publicClient, setPublicClient] = useState();
+ const [message, setMessage] = useState('this is a secret');
+ const [encrypting, setEncrypting] = useState(false);
+ const [encryptedText, setEncryptedText] = useState('');
+ const [decrypting, setDecrypting] = useState(false);
const [decryptedMessage, setDecryptedMessage] = useState(
'',
);
- const loadWeb3Provider = async () => {
+ const loadWeb3Clients = async () => {
if (!window.ethereum) {
console.error('You need to connect to your wallet first');
+ return;
}
- const provider = new ethers.providers.Web3Provider(window.ethereum, 'any');
- const { chainId } = await provider.getNetwork();
+ const publicClient = createPublicClient({
+ transport: custom(window.ethereum),
+ });
+ const walletClient = createWalletClient({
+ transport: custom(window.ethereum),
+ });
+ const chainId = await walletClient.getChainId();
+
const mumbaiChainId = 80001;
if (chainId !== mumbaiChainId) {
// Switch to Polygon Mumbai testnet
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
- params: [{ chainId: hexlify(mumbaiChainId) }],
+ params: [{ chainId: toHex(mumbaiChainId) }],
});
}
- await provider.send('eth_requestAccounts', []);
- setProvider(provider);
+ await walletClient.getAddresses();
+ setPublicClient(publicClient);
+ setWalletClient(walletClient);
};
useEffect(() => {
- loadWeb3Provider();
+ loadWeb3Clients();
}, []);
const { isInit, encryptDataToBytes, decryptDataFromBytes } = useTaco({
domain,
- provider,
ritualId,
+ walletClient,
+ publicClient,
});
- if (!isInit || !provider) {
+ if (!isInit || !walletClient) {
return Loading...
;
}
const encryptMessage = async () => {
- if(!provider) return;
- setEncrypting(true)
+ if (!walletClient) {
+ return;
+ }
+ setEncrypting(true);
try {
- const signer = provider.getSigner();
const hasPositiveBalance = new conditions.RpcCondition({
chain: 80001,
method: 'eth_getBalance',
@@ -79,41 +92,60 @@ function App() {
const encryptedBytes = await encryptDataToBytes(
message,
hasPositiveBalance,
- signer,
+ publicClient,
+ walletClient,
);
if (encryptedBytes) {
- setEncryptedText(toHexString(encryptedBytes))
+ setEncryptedText(toHexString(encryptedBytes));
}
} catch (e) {
- console.log(e)
+ console.log(e);
}
- setEncrypting(false)
- }
+ setEncrypting(false);
+ };
const decryptMessage = async () => {
- if(!encryptedText || !provider) return
+ if (!encryptedText || !walletClient) {
+ return;
+ }
try {
- setDecrypting(true)
- const signer = provider.getSigner();
-
+ setDecrypting(true);
console.log('Decrypting message...');
const decryptedMessage = await decryptDataFromBytes(
fromHexString(encryptedText),
- signer,
+ publicClient,
+ walletClient,
);
if (decryptedMessage) {
setDecryptedMessage(fromBytes(decryptedMessage));
}
} catch (e) {
- console.log(e)
+ console.log(e);
}
- setDecrypting(false)
+ setDecrypting(false);
};
return (
-
Secret message: setMessage(e.target.value)} onClick={encryptMessage}/> {encrypting && 'Encrypting...'}
- Encrypted message: setEncryptedText(e.target.value)} /> {decrypting && 'Decrypting...'}
+
+ Secret message:{' '}
+ setMessage(e.target.value)}
+ onClick={encryptMessage}
+ />
+
+ {encrypting && 'Encrypting...'}
+
+
+ Encrypted message:{' '}
+ setEncryptedText(e.target.value)}
+ />
+
+ {decrypting && 'Decrypting...'}
+
{decryptedMessage && Decrypted message: {decryptedMessage}
}
);
diff --git a/examples/taco/react/src/hooks/useTaco.ts b/examples/taco/react/src/hooks/useTaco.ts
index ed7732eb6..653a15005 100644
--- a/examples/taco/react/src/hooks/useTaco.ts
+++ b/examples/taco/react/src/hooks/useTaco.ts
@@ -1,4 +1,5 @@
import {
+ conditions,
decrypt,
Domain,
encrypt,
@@ -6,18 +7,17 @@ import {
initialize,
ThresholdMessageKit,
} from '@nucypher/taco';
-import { Condition } from '@nucypher/taco/src/conditions';
-import { ethers } from 'ethers';
import { useCallback, useEffect, useState } from 'react';
+import { PublicClient, WalletClient } from 'viem';
export default function useTaco({
ritualId,
domain,
- provider,
}: {
ritualId: number;
domain: Domain;
- provider: ethers.providers.Provider | undefined;
+ publicClient?: PublicClient;
+ walletClient?: WalletClient;
}) {
const [isInit, setIsInit] = useState(false);
@@ -26,38 +26,47 @@ export default function useTaco({
}, []);
const decryptDataFromBytes = useCallback(
- async (encryptedBytes: Uint8Array, signer?: ethers.Signer) => {
- if (!isInit || !provider) return;
+ async (
+ encryptedBytes: Uint8Array,
+ publicClient?: PublicClient,
+ walletClient?: WalletClient,
+ ) => {
+ if (!isInit || !publicClient || !walletClient) {
+ return;
+ }
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
return decrypt(
- provider,
+ publicClient,
domain,
messageKit,
getPorterUri(domain),
- signer,
+ walletClient,
);
},
- [isInit, provider, domain],
+ [isInit, domain],
);
const encryptDataToBytes = useCallback(
async (
message: string,
- condition: Condition,
- encryptorSigner: ethers.Signer,
+ condition: conditions.Condition,
+ publicClient?: PublicClient,
+ walletClient?: WalletClient,
) => {
- if (!isInit || !provider) return;
+ if (!isInit || !publicClient || !walletClient) {
+ return;
+ }
const messageKit = await encrypt(
- provider,
+ publicClient,
domain,
message,
condition,
ritualId,
- encryptorSigner,
+ walletClient,
);
return messageKit.toBytes();
},
- [isInit, provider, domain, ritualId],
+ [isInit, domain, ritualId],
);
return {
diff --git a/examples/taco/react/src/index.tsx b/examples/taco/react/src/index.tsx
index 253d3f9b3..3f83eeaea 100644
--- a/examples/taco/react/src/index.tsx
+++ b/examples/taco/react/src/index.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
-import './index.css'
import App from './App';
+import './index.css';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement,
diff --git a/examples/taco/react/src/react-app-env.d.ts b/examples/taco/react/src/react-app-env.d.ts
deleted file mode 100644
index 8f8826530..000000000
--- a/examples/taco/react/src/react-app-env.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-import { ExternalProvider } from '@ethersproject/providers';
-
-declare global {
- interface Window {
- ethereum?: ExternalProvider;
- }
-}
diff --git a/examples/taco/webpack-5/package.json b/examples/taco/webpack-5/package.json
index 4266b882a..3a67f4853 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.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.7.4"
- },
- "peerDependencies": {
- "ethers": "^5.7.2"
}
}
diff --git a/examples/taco/webpack-5/src/index.html b/examples/taco/webpack-5/src/index.html
index ad1f3fd35..6aaef3537 100644
--- a/examples/taco/webpack-5/src/index.html
+++ b/examples/taco/webpack-5/src/index.html
@@ -8,7 +8,8 @@
+ javascript in your browser.
Check console for results